#include "Gui.h"

using namespace Ogre;
using namespace std;

Gui::Gui(Ogre::Root *mRoot){
	this->mRoot=mRoot;
	editor = new MapEditor(mRoot);
	createScene();        
	setupCEGUI();

}

Gui::~Gui(void){
}
void Gui::setupCEGUI()
{

    CEGUI::OgreCEGUIRenderer *mRenderer;
    CEGUI::System *mSystem;

	// CEGUI setup
	mRenderer = new CEGUI::OgreCEGUIRenderer(mRoot->getAutoCreatedWindow(), Ogre::RENDER_QUEUE_OVERLAY, false, 3000, mRoot->getSceneManager("Default SceneManager"));
	mSystem = new CEGUI::System(mRenderer);
	CEGUI::SchemeManager::getSingleton().loadScheme((CEGUI::utf8*)"TaharezLookSkin.scheme");
	mSystem->setDefaultMouseCursor((CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MouseArrow");
	mSystem->setDefaultFont((CEGUI::utf8*)"BlueHighway-12");
	CEGUI::MouseCursor::getSingleton().setImage(CEGUI::System::getSingleton().getDefaultMouseCursor());

	CEGUI::WindowManager *win = CEGUI::WindowManager::getSingletonPtr();
	//CEGUI::Window *sheet = win->createWindow("DefaultGUISheet", "Editor/Sheet");
	CEGUI::Window* sheet = 
            CEGUI::WindowManager::getSingleton().loadWindowLayout(
                (CEGUI::utf8*)"editorgui.layout"); 

	CEGUI::Window *quit = win->getWindow((CEGUI::utf8*)"EditorGui/TabCtrl/MainPage/QuitButton");
		quit->subscribeEvent(
			CEGUI::PushButton::EventClicked, 
			CEGUI::Event::Subscriber(&Gui::handleQuit, this));
	CEGUI::Window *load = win->getWindow((CEGUI::utf8*)"EditorGui/TabCtrl/MainPage/LoadButton");
		load->subscribeEvent(
			CEGUI::PushButton::EventClicked, 
			CEGUI::Event::Subscriber(&Gui::loadModelMenu, this));

	mSystem->setGUISheet(sheet);
	
    CEGUI::Combobox* objectComboBox = (CEGUI::Combobox*)CEGUI::WindowManager::getSingleton().getWindow("EditorGui/TabCtrl/Page2/ObjectTypeList");

	fillList(objectComboBox,"..\\..\\media\\models");

    win->getWindow((CEGUI::utf8*)"EditorGui/TabCtrl/Page2/ObjectTypeList")
		->subscribeEvent(
			CEGUI::Combobox::EventListSelectionAccepted, 
			CEGUI::Event::Subscriber(&Gui::loadModelMenu, this));

    win->getWindow((CEGUI::utf8*)"EditorGui/TabCtrl/Page3/Translate")
		->subscribeEvent(
			CEGUI::PushButton::EventClicked, 
			CEGUI::Event::Subscriber(&Gui::translateModel, this));

    win->getWindow((CEGUI::utf8*)"EditorGui/TabCtrl/Page3/Scale")
		->subscribeEvent(
			CEGUI::PushButton::EventClicked, 
			CEGUI::Event::Subscriber(&Gui::scaleModel, this));

    win->getWindow((CEGUI::utf8*)"EditorGui/TabCtrl/Page3/Rotate")
		->subscribeEvent(
			CEGUI::PushButton::EventClicked, 
			CEGUI::Event::Subscriber(&Gui::rotateModel, this));

    win->getWindow((CEGUI::utf8*)"EditorGui/TabCtrl/Page3/Duplicate")
		->subscribeEvent(
			CEGUI::PushButton::EventClicked, 
			CEGUI::Event::Subscriber(&Gui::duplicateModel, this));

    win->getWindow((CEGUI::utf8*)"EditorGui/TabCtrl/Page3/Move")
		->subscribeEvent(
			CEGUI::PushButton::EventClicked, 
			CEGUI::Event::Subscriber(&Gui::moveModel, this));

}

bool Gui::handleQuit(const CEGUI::EventArgs& e){

    Constants::instance()->setEnd();
    return true;
}

bool Gui::loadModelMenu(const CEGUI::EventArgs& e){

	toggleMenu();
	int actionadd=ST_ADDING;
	Constants::instance()->setState(actionadd);
    const CEGUI::WindowEventArgs& windowEventArgs = static_cast<const CEGUI::WindowEventArgs&>(e);
    CEGUI::ListboxItem* item = static_cast<CEGUI::Combobox*>(windowEventArgs.window)->getSelectedItem();
	editor->addModel(item->getText());
	return true;
}

bool Gui::translateModel(const CEGUI::EventArgs& e){

	toggleMenu();
	editor->startTranslatingObject();
	return true;
}

bool Gui::scaleModel(const CEGUI::EventArgs& e){

	toggleMenu();
	editor->startScalingObject();
	return true;
}

bool Gui::rotateModel(const CEGUI::EventArgs& e){

	toggleMenu();
	editor->startRotatingObject();
	return true;
}

bool Gui::duplicateModel(const CEGUI::EventArgs& e){

	toggleMenu();
	editor->startDuplicatingObject();
	return true;
}

bool Gui::moveModel(const CEGUI::EventArgs& e){

	toggleMenu();
	editor->startMovingObject();
	return true;
}

void Gui::fillList(CEGUI::Combobox* objectComboBox, string _path){

	HANDLE fh;
    CEGUI::ListboxTextItem* item;
	int i=0;
	int    filecnt=0;
	char	 path[MAX_PATH];
	char	 tmppath[MAX_PATH];

	WIN32_FIND_DATA *fd;
	fd = (WIN32_FIND_DATA*) malloc(sizeof(WIN32_FIND_DATA));

	fixpath(_path.c_str(),path);
	strcat(path,"*");

	fh = FindFirstFile((LPCSTR) path,fd);

	if(fh != INVALID_HANDLE_VALUE)
	{
		do
		{
			filecnt++;
			if(fd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			{

				if((0 != strcmp(fd->cFileName,".")) && (0 != strcmp(fd->cFileName,"..")))
				{
					fixpath(_path.c_str(),tmppath);
					strcat(tmppath,fd->cFileName);
					fixpath(tmppath,tmppath);
					item = new CEGUI::ListboxTextItem((CEGUI::utf8*)fd->cFileName, i);
					objectComboBox->addItem(item);
					i++;
				}
			}
			else
			{

				item = new CEGUI::ListboxTextItem((CEGUI::utf8*)fd->cFileName, i);
				objectComboBox->addItem(item);
				i++;
			}


		}
		while(FindNextFile(fh,fd));
	}

	FindClose(fh);

}


//------------------------------------------------------------------------------------------------------------------
// fixpath() - Adds \ to the end of a path if not present.
//------------------------------------------------------------------------------------------------------------------
int Gui::fixpath(const char *inpath, char *outpath)
{
  int   n=0;

  strcpy(outpath,inpath);

  while(inpath[n]) n++;

  if(inpath[n-1] != '\\')
  {
    strcat(outpath,"\\");
    return 1;
  }

  return 0;
}

void Gui::toggleMenu(){

	int state=Constants::instance()->getState();
	int actionstate=Constants::instance()->getActionState();
	int menustateon=ST_MENUON;
	int menustateoff=ST_MENUOFF;

	int movingmouse=ST_MOVINGMOUSE;
	int staticmouse=ST_STATICMOUSE;

	int movingcamera=ST_MOVINGCAMERA;
	int staticcamera=ST_STATICCAMERA;

	int noactionstate=ST_NOACTION;
	int actionAdd=ST_ADDING;
	int actionSelect=ST_SELECTING;

	CEGUI::WindowManager *win;
	CEGUI::Window *sheet;
	CEGUI::MouseCursor *mouse;
	mouse = CEGUI::MouseCursor::getSingletonPtr();
	if( state==menustateon ){
		Constants::instance()->setState(menustateoff);
		win = CEGUI::WindowManager::getSingletonPtr();
		sheet = win->getWindow((CEGUI::utf8*)"root");
		sheet->setVisible(false);
		if(actionstate==actionAdd || actionstate==noactionstate){
			mouse->setVisible(false);
			Constants::instance()->setMouseState(staticmouse);
			Constants::instance()->setCameraState(movingcamera);
		}
	}
	else{
		Constants::instance()->setState(menustateon);
		win = CEGUI::WindowManager::getSingletonPtr();
		sheet = win->getWindow((CEGUI::utf8*)"root");
		sheet->setVisible(true);
		mouse->setVisible(true);
		Constants::instance()->setActionState(noactionstate);
	}
	
}

void Gui::createScene()
{
	editor->createScene();

}

void Gui::keyPressed(const OIS::KeyEvent &e){
	switch (e.key)
	{
		/*
		case OIS::KC_1:
			mCamera->getParentSceneNode()->detachObject(mCamera);
			mCamNode = mSceneMgr->getSceneNode("CamNode1");
			mCamNode->attachObject(mCamera);
			break;

		case OIS::KC_2:
			mCamera->getParentSceneNode()->detachObject(mCamera);
			mCamNode = mSceneMgr->getSceneNode("CamNode2");
			mCamNode->attachObject(mCamera);
			break;
*/
		case OIS::KC_UP:
		case OIS::KC_W:
			editor->moveFw();
			break;

		case OIS::KC_DOWN:
		case OIS::KC_S:
			editor->moveBk();
			break;

		case OIS::KC_LEFT:
		case OIS::KC_A:
			editor->moveLeft();
			break;

		case OIS::KC_RIGHT:
		case OIS::KC_D:
			editor->moveRight();
			break;

		case OIS::KC_PGDOWN:
		case OIS::KC_E:
			editor->moveDown();
			break;

		case OIS::KC_PGUP:
		case OIS::KC_Q:
			editor->moveUp();
			break;

		case OIS::KC_F:
			editor->toggleFog();
			break;

		case OIS::KC_LCONTROL:
		case OIS::KC_RCONTROL:
			editor->ctrlStateToggle();
			break;
	}

}
void Gui::keyReleased(const OIS::KeyEvent &e){
	switch (e.key)
	{
		case OIS::KC_UP:
		case OIS::KC_W:
			editor->stopFw();
			break;

		case OIS::KC_DOWN:
		case OIS::KC_S:
			editor->stopBk();
			break;

		case OIS::KC_LEFT:
		case OIS::KC_A:
			editor->stopLeft();
			break;

		case OIS::KC_RIGHT:
		case OIS::KC_D:
			editor->stopRight();
			break;

		case OIS::KC_PGDOWN:
		case OIS::KC_E:
			editor->stopDown();
			break;

		case OIS::KC_PGUP:
		case OIS::KC_Q:
			editor->stopUp();
			break;

		case OIS::KC_LCONTROL:
		case OIS::KC_RCONTROL:
			editor->ctrlStateToggle();
			break;

		default:
			break;
	} // switch
	//return true;
	
}

void Gui::updateGraphics(const FrameEvent &evt){
	editor->updateGraphics(evt);

}

void Gui::updateCam(const OIS::MouseEvent &evt){
	editor->updateCam(evt);

}

void Gui::mousePressed(const OIS::MouseEvent &evt){
	editor->mousePressed(evt);

}


